<?php
/**
 * URI封装对象
 * 
 * @version $Id$
 * @package if
 * @subpackage util.net
 * @since 1.0
 */
class IURI extends IObject {
	private $info = array();
	private $uri;
	
	/**
	 * 构造
	 *
	 * @param string $uri URI字符串
	 */
	function __construct($uri) {
		$this->uri = $uri;
		$this->info = @parse_url($uri);
		if (!$this->info) {
			//再尝试一次
			if (strstr($uri, "?")) {
				list($url, $query) = explode("?", $this->uri, 2);
				$this->info = @parse_url($url);
				if (!$this->info) {
					throw new INetException("invalid uri '{$uri}'", 0x100126);
				}
				else {
					if (strstr($query, "#")) {
						list($query, $fragment) = explode("#", $query, 2);
						$this->info["query"] = $query;
						$this->info["fragment"] = $fragment;
					}
					else {
						$this->info["query"] = $query;
					}
				}
			}
			else {
				throw new INetException("invalid uri '{$uri}'", 0x100127);
			}
		}
	}
	
	/**
	 * 取得片段（锚点）
	 *
	 * @return string
	 */
	function fragment() {
		return $this->value("fragment");
	}
	
	/**
	 * 取得host值
	 *
	 * @return string
	 */
	function host() {
		return $this->value("host");	
	}
	
	/**
	 * 取得pass值
	 *
	 * @return string
	 */
	function pass() {
		return $this->value("pass");	
	}
	
	/**
	 * 取得path值
	 *
	 * @return string
	 */	
	function path() {
		$path = $this->value("path");
		if (if_empty($path)) {
			$path = "/";
		}
		return $path;
	}
	
	/**
	 * 取得port值
	 * 
	 * 从1.0起，如果没有指定端口，则返回80或443(https)
	 *
	 * @return integer
	 */	
	function port() {
		$ports = array(
			"http" => 80,
			"https" => 443,
			"ftp" => 21,
			"ftps" => 990
		);
		$port = $this->value("port");	
		if (!$port) {
			$schema = strtolower($this->scheme());
			if (isset($ports[$schema])) {
				return $ports[$schema];
			}
		}
		return $port;
	}
	
	/**
	 * 取得query值
	 *
	 * @return string
	 */	
	function query() {
		return $this->value("query");
	}
	
	/**
	 * 取得scheme（协议）值
	 *
	 * @return string
	 */	
	function scheme() {
		return $this->value("scheme");
	}
	
	/**
	 * 取得user值
	 *
	 * @return string
	 */	
	function user() {
		return $this->value("user");
	}
	
	/**
	 * 取得一个名称对应的值
	 *
	 * @param string $name 名称
	 * @return string
	 */
	private function value($name) {
		if (isset($this->info[$name])) {
			return $this->info[$name];
		}
		return null;
	}
	
	/**
	 * 转化成字符串
	 *
	 * @return string
	 */
	function __toString() {
		return $this->uri;
	}
	
	function segment($index) {
		if (!isset($_SERVER["PATH_INFO"])) {
			return null;
		}
		$pathinfo = $_SERVER["PATH_INFO"];
		$segments = explode("/", $pathinfo);
		array_shift($segments);
		return isset($segments[$index])?$segments[$index]:null;
	}
	
	/**
	 * 将一个数组编码成一个可以用作URL的查询字符串
	 * 
	 * 从1.1.0开始起，支持多级数组
	 *
	 * @param array $query 查询的参数数组
	 * @return string
	 * @since 1.0.3
	 */
	static function encodeQuery(array $query) {
		if (function_exists("http_build_query")) {
			return http_build_query($query);
		}
		return self::_encodeQuery($query);
	}
	
	/**
	 * Enter description here...
	 *
	 * @param array $query
	 * @param unknown_type $prefix
	 * @return unknown
	 * @since 1.1.0
	 */
	private static function _encodeQuery(array $query, $prefix = null) {
		$_query = array();
		foreach ($query as $param => $value) {
			$param = is_null($prefix) ? $param : $prefix . "[" . $param . "]";
			if (is_array($value)) {
				$_query[] = self::_encodeQuery($value, $param);
			}
			else {
				$_query[] = urlencode($param) . "=" . urlencode($value);
			}
		}
		return implode("&", $_query);
	}
	
	/**
	 * 设定参数值
	 *
	 * @param string $name 参数名
	 * @param mixed $value 参数值
	 * @since 1.1.0
	 */
	function set($name, $value) {
		$this->info[$name] = $value;
	}
	
	/**
	 * 是否为安全连接
	 *
	 * @return boolean
	 * @since 1.1.0
	 */
	function isSecure() {
		return strtolower($this->scheme()) == "https";
	}
}

?>